<template>
  <div class="chord-dict-container">
    <home-header />
    <div class="chord-dict-content">
      <div class="chord-dict-card">
        <div class="search-section">
          <el-form class="chord-dict-form" @submit.native.prevent="onQuery">
            <div class="search-row">
              <el-form-item label="调式" class="key-select">
                <el-select v-model="selectedKey" placeholder="选择调式" @change="onKeyChange" :disabled="isKeySearchMode">
                  <el-option-group label="大调">
                    <el-option 
                      v-for="key in majorKeys" 
                      :key="key.value" 
                      :label="key.label" 
                      :value="key.value" 
                    />
                  </el-option-group>
                  <el-option-group label="小调">
                    <el-option 
                      v-for="key in minorKeys" 
                      :key="key.value" 
                      :label="key.label" 
                      :value="key.value" 
                    />
                  </el-option-group>
                </el-select>
              </el-form-item>
              <el-form-item label="和弦级数" class="degree-select">
                <el-select v-model="selectedDegree" placeholder="选择和弦级数" @change="onDegreeChange" :disabled="isKeySearchMode">
                  <el-option-group label="自然音阶和弦">
                    <el-option label="一级和弦 (I)" value="1" />
                    <el-option label="二级和弦 (II)" value="2" />
                    <el-option label="三级和弦 (III)" value="3" />
                    <el-option label="四级和弦 (IV)" value="4" />
                    <el-option label="五级和弦 (V)" value="5" />
                    <el-option label="六级和弦 (VI)" value="6" />
                    <el-option label="七级和弦 (VII)" value="7" />
                  </el-option-group>
                </el-select>
              </el-form-item>
              <el-form-item label="和弦类型" class="chord-type-select">
                <el-select v-model="selectedChordType" placeholder="选择和弦类型" @change="onChordTypeChange" :disabled="isKeySearchMode">
                  <el-option label="三和弦" value="triad" />
                  <el-option label="七和弦" value="seventh" />
                  <el-option label="九和弦" value="ninth" />
                  <el-option label="十一和弦" value="eleventh" />
                  <el-option label="十三和弦" value="thirteenth" />
                </el-select>
              </el-form-item>
              <el-form-item label="和弦子类型" class="chord-subtype-select">
                <el-select v-model="selectedSubType" placeholder="选择和弦子类型" @change="onSubTypeChange" :disabled="isKeySearchMode">
                  <el-option 
                    v-for="subType in availableSubTypes" 
                    :key="subType.value" 
                    :label="subType.label" 
                    :value="subType.value" 
                  />
                </el-select>
              </el-form-item>
              <!-- 转位下拉菜单，仅在非按键找音模式下显示 -->
              <el-form-item v-if="!isKeySearchMode" label="转位" class="inversion-select">
                <el-select v-model="selectedInversion" @change="onInversionChange">
                  <el-option v-for="(inv, idx) in inversionOptions" :key="idx" :label="inv.label" :value="inv.value" />
                </el-select>
              </el-form-item>
              <div class="btn-group">
                <el-form-item class="search-btn" v-if="!isKeySearchMode">
                  <el-button type="primary" class="chord-dict-btn" @click="onQuery">查询</el-button>
                </el-form-item>
                <el-form-item class="key-search-btn">
                  <el-button type="primary" class="chord-dict-btn" @click="toggleKeySearchMode">{{ isKeySearchMode ? '返回' : '按键找音' }}</el-button>
                </el-form-item>
                <el-form-item v-if="isKeySearchMode" class="confirm-btn">
                  <el-button type="success" class="chord-dict-btn" @click="onConfirmKeySearch" :disabled="selectedNotes.length < 3">确定</el-button>
                </el-form-item>
              </div>
            </div>
          </el-form>
        </div>
        <div v-if="chordList.length > 0" class="chord-list">
          <h3 class="chord-list-title">当前条件下的和弦：</h3>
          <el-table :data="chordList" style="width: 100%" border>
            <el-table-column prop="enName" label="和弦英文名" width="180" />
            <el-table-column prop="intervals" label="和弦结构" width="180" />
            <el-table-column prop="cnName" label="中文名" />
            <el-table-column prop="notes" label="音符" />
            <el-table-column label="试听" width="200">
              <template #default="scope">
                <el-button size="mini" @click="playChord(scope.row.notes)">试听</el-button>
                <el-button size="mini" @click="playArpeggio(scope.row.notes)">琶音</el-button>
              </template>
            </el-table-column>
          </el-table>
          <!-- 和弦理论说明区块 -->
          <div class="chord-theory-box" v-if="chordList.length > 0">
            <div class="chord-theory-header">
              <i class="el-icon-info" style="font-size:17px;margin-right:6px;"></i>
              <span style="color:#222;">和弦理论/用法说明</span>
            </div>
            <div class="chord-theory-content">
              <div v-html="theoryText"></div>
            </div>
          </div>
        </div>
        <el-empty v-if="showEmpty" description="未找到符合条件的和弦" />
        
        <!-- 钢琴键盘区域 -->
        <div class="keyboard-section">
          <div v-if="chordList.length > 0 || isKeySearchMode" class="keyboard-box">
            <div class="piano-bottom">
              <div class="piano">
                <div v-for="(key, index) in pianoKeys" :key="index"
                     :id="key"
                     :data-id="key"
                     class="piano-key"
                     :class="[{'black': key.includes('#') || key.includes('b')}, highlightedKeys.includes(index) ? 'highlighted-chord' : '']"
                     @click="handlePianoKeyClick(index)">
                  <span v-if="noteNames[index]" :class="noteNames[index].pitch">
                    {{ noteNames[index].name }}
                  </span>
                </div>
              </div>
              <ul class="piano-group">
                <li v-for="(width, index) in groupWidths" 
                    :key="index" 
                    class="group"
                    :style="{ width: width }">
                  {{ index + 1 }}组
                </li>
              </ul>
            </div>
          </div>
          <el-empty v-else description="请点击查询或按键找音按钮查看和弦" />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import HomeHeader from '@/components/HomeHeader.vue'

// 调式定义
const MAJOR_KEYS = [
  { label: 'C大调', value: 'C' },
  { label: 'G大调', value: 'G' },
  { label: 'D大调', value: 'D' },
  { label: 'A大调', value: 'A' },
  { label: 'E大调', value: 'E' },
  { label: 'B大调', value: 'B' },
  { label: 'F#大调', value: 'F#' },
  { label: 'C#大调', value: 'C#' },
  { label: 'F大调', value: 'F' },
  { label: 'Bb大调', value: 'Bb' },
  { label: 'Eb大调', value: 'Eb' },
  { label: 'Ab大调', value: 'Ab' }
]

const MINOR_KEYS = [
  { label: 'a小调', value: 'a' },
  { label: 'e小调', value: 'e' },
  { label: 'b小调', value: 'b' },
  { label: 'f#小调', value: 'f#' },
  { label: 'c#小调', value: 'c#' },
  { label: 'g#小调', value: 'g#' },
  { label: 'd#小调', value: 'd#' },
  { label: 'a#小调', value: 'a#' },
  { label: 'd小调', value: 'd' },
  { label: 'g小调', value: 'g' },
  { label: 'c小调', value: 'c' },
  { label: 'f小调', value: 'f' }
]

// 和弦子类型定义
const CHORD_SUB_TYPES = {
  triad: [
    { label: '大三和弦', value: 'major' },
    { label: '小三和弦', value: 'minor' },
    { label: '增三和弦', value: 'augmented' },
    { label: '减三和弦', value: 'diminished' },
    { label: '挂二和弦', value: 'sus2' },
    { label: '挂四和弦', value: 'sus4' }
  ],
  seventh: [
    { label: '大七和弦', value: 'major7' },
    { label: '属七和弦', value: 'dominant7' },
    { label: '小七和弦', value: 'minor7' },
    { label: '半减七和弦', value: 'half-diminished7' },
    { label: '减七和弦', value: 'diminished7' }
  ],
  ninth: [
    { label: '大九和弦', value: 'major9' },
    { label: '属九和弦', value: 'dominant9' },
    { label: '小九和弦', value: 'minor9' }
  ],
  eleventh: [
    { label: '大十一和弦', value: 'major11' },
    { label: '属十一和弦', value: 'dominant11' },
    { label: '小十一和弦', value: 'minor11' }
  ],
  thirteenth: [
    { label: '大十三和弦', value: 'major13' },
    { label: '属十三和弦', value: 'dominant13' },
    { label: '小十三和弦', value: 'minor13' }
  ]
}

// 和弦模板定义
const CHORD_TEMPLATES = {
  triad: {
    major: {
      intervals: '1 3 5',
      suffix: '',
      cnSuffix: '大三和弦'
    },
    minor: {
      intervals: '1 b3 5',
      suffix: 'm',
      cnSuffix: '小三和弦'
    },
    augmented: {
      intervals: '1 3 #5',
      suffix: 'aug',
      cnSuffix: '增三和弦'
    },
    diminished: {
      intervals: '1 b3 b5',
      suffix: 'dim',
      cnSuffix: '减三和弦'
    },
    sus2: {
      intervals: '1 2 5',
      suffix: 'sus2',
      cnSuffix: '挂二和弦'
    },
    sus4: {
      intervals: '1 4 5',
      suffix: 'sus4',
      cnSuffix: '挂四和弦'
    }
  },
  seventh: {
    major7: {
      intervals: '1 3 5 7',
      suffix: 'maj7',
      cnSuffix: '大七和弦'
    },
    dominant7: {
      intervals: '1 3 5 b7',
      suffix: '7',
      cnSuffix: '属七和弦'
    },
    minor7: {
      intervals: '1 b3 5 b7',
      suffix: 'm7',
      cnSuffix: '小七和弦'
    },
    'half-diminished7': {
      intervals: '1 b3 b5 b7',
      suffix: 'ø7',
      cnSuffix: '半减七和弦'
    },
    diminished7: {
      intervals: '1 b3 b5 bb7',
      suffix: 'dim7',
      cnSuffix: '减七和弦'
    }
  },
  ninth: {
    major9: {
      intervals: '1 3 5 7 9',
      suffix: 'maj9',
      cnSuffix: '大九和弦'
    },
    dominant9: {
      intervals: '1 3 5 b7 9',
      suffix: '9',
      cnSuffix: '属九和弦'
    },
    minor9: {
      intervals: '1 b3 5 b7 9',
      suffix: 'm9',
      cnSuffix: '小九和弦'
    }
  },
  eleventh: {
    major11: {
      intervals: '1 3 5 7 9 11',
      suffix: 'maj11',
      cnSuffix: '大十一和弦'
    },
    dominant11: {
      intervals: '1 3 5 b7 9 11',
      suffix: '11',
      cnSuffix: '属十一和弦'
    },
    minor11: {
      intervals: '1 b3 5 b7 9 11',
      suffix: 'm11',
      cnSuffix: '小十一和弦'
    }
  },
  thirteenth: {
    major13: {
      intervals: '1 3 5 7 9 11 13',
      suffix: 'maj13',
      cnSuffix: '大十三和弦'
    },
    dominant13: {
      intervals: '1 3 5 b7 9 11 13',
      suffix: '13',
      cnSuffix: '属十三和弦'
    },
    minor13: {
      intervals: '1 b3 5 b7 9 11 13',
      suffix: 'm13',
      cnSuffix: '小十三和弦'
    }
  }
}

// 音阶定义
const NOTES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
const FLAT_NOTES = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B']

// 音程定义（半音数）
const INTERVALS = {
  '1': 0,    // 一度
  'b2': 1,   // 小二度
  '2': 2,    // 大二度
  'b3': 3,   // 小三度
  '3': 4,    // 大三度
  '4': 5,    // 纯四度
  'b5': 6,   // 减五度
  '5': 7,    // 纯五度
  '#5': 8,   // 增五度
  'b6': 8,   // 小六度
  '6': 9,    // 大六度
  'b7': 10,  // 小七度
  '7': 11,   // 大七度
  'bb7': 9,  // 减七度
  '8': 12,   // 八度
  '9': 14,   // 大九度
  'b9': 13,  // 小九度
  '11': 17,  // 十一度
  '13': 21   // 十三度
}

// 获取音符在音阶中的索引
function getNoteIndex(note, useFlats = false) {
  const scale = useFlats ? FLAT_NOTES : NOTES
  return scale.indexOf(note.toUpperCase())
}

// 根据根音和半音数计算音符
function getNoteByInterval(rootNote, semitones, useFlats = false) {
  const scale = useFlats ? FLAT_NOTES : NOTES
  const rootIndex = getNoteIndex(rootNote, useFlats)
  if (rootIndex === -1) return null
  
  const noteIndex = (rootIndex + semitones) % 12
  return scale[noteIndex]
}

// 判断是否应该使用降号
function shouldUseFlats(key) {
  // 这些调式通常使用降号
  const flatKeys = ['F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb', 'Cb']
  return flatKeys.includes(key)
}

// 获取和弦音符
function getChordNotes(key, chordType, subType) {
  const template = CHORD_TEMPLATES[chordType][subType]
  if (!template) return null

  const useFlats = shouldUseFlats(key)
  const intervals = template.intervals.split(' ')
  const notes = [key] // 根音

  // 计算每个音程对应的音符
  for (let i = 1; i < intervals.length; i++) {
    const interval = intervals[i]
    const semitones = INTERVALS[interval]
    if (semitones === undefined) continue

    const note = getNoteByInterval(key, semitones, useFlats)
    if (note) notes.push(note)
  }

  return notes
}

// 获取和弦名称
function getChordName(key, chordType, subType) {
  const template = CHORD_TEMPLATES[chordType][subType]
  if (!template) return null

  return {
    enName: key + template.suffix,
    intervals: template.intervals,
    cnName: key + template.cnSuffix
  }
}

function matchChord(inputNotes, key, chordType, subType) {
  const notes = inputNotes.map(n => n.trim().toUpperCase()).sort()
  const chordNotes = getChordNotes(key, chordType, subType)
  if (!chordNotes) return null

  if (chordNotes.length === notes.length && chordNotes.slice().sort().join(',') === notes.join(',')) {
    return getChordName(key, chordType, subType)
  }
  return null
}

// 大调音阶
const MAJOR_SCALE = [0, 2, 4, 5, 7, 9, 11] // C D E F G A B
// 小调音阶
const MINOR_SCALE = [0, 2, 3, 5, 7, 8, 10] // C D Eb F G Ab Bb

// 获取调式音阶
function getScale(key) {
  const isMajor = key === key.toUpperCase()
  return isMajor ? MAJOR_SCALE : MINOR_SCALE
}

// 根据调式和级数获取根音
function getRootNote(key, degree) {
  const scale = getScale(key)
  const rootIndex = getNoteIndex(key)
  if (rootIndex === -1) return null

  const degreeIndex = (parseInt(degree) - 1) % 7
  const semitones = scale[degreeIndex]
  return getNoteByInterval(key, semitones, shouldUseFlats(key))
}

// 添加钢琴键盘相关数据
const PIANO_KEYS = [
  'A0', 'A#0/Bb0', 'B0',
  'C1', 'C#1/Db1', 'D1', 'D#1/Eb1', 'E1', 'F1', 'F#1/Gb1', 'G1', 'G#1/Ab1',
  'A1', 'A#1/Bb1', 'B1',
  'C2', 'C#2/Db2', 'D2', 'D#2/Eb2', 'E2', 'F2', 'F#2/Gb2', 'G2', 'G#2/Ab2',
  'A2', 'A#2/Bb2', 'B2',
  'C3', 'C#3/Db3', 'D3', 'D#3/Eb3', 'E3', 'F3', 'F#3/Gb3', 'G3', 'G#3/Ab3',
  'A3', 'A#3/Bb3', 'B3',
  'C4', 'C#4/Db4', 'D4', 'D#4/Eb4', 'E4', 'F4', 'F#4/Gb4', 'G4', 'G#4/Ab4',
  'A4', 'A#4/Bb4', 'B4',
  'C5', 'C#5/Db5', 'D5', 'D#5/Eb5', 'E5', 'F5', 'F#5/Gb5', 'G5', 'G#5/Ab5',
  'A5', 'A#5/Bb5', 'B5',
  'C6', 'C#6/Db6', 'D6', 'D#6/Eb6', 'E6', 'F6', 'F#6/Gb6', 'G6', 'G#6/Ab6',
  'A6', 'A#6/Bb6', 'B6',
  'C7', 'C#7/Db7', 'D7', 'D#7/Eb7', 'E7', 'F7', 'F#7/Gb7', 'G7', 'G#7/Ab7',
  'A7', 'A#7/Bb7', 'B7',
  'C8'
]

const GROUP_WIDTHS = ['3.75%', '13.35%', '13.35%', '13.35%', '13.35%', '13.35%', '13.35%', '13.35%', '1.95%']

export default {
  name: 'ChordDictionary',
  components: { HomeHeader },
  data() {
    return {
      showEmpty: false,
      selectedKey: 'C',
      selectedDegree: '1',
      selectedChordType: 'triad',
      selectedSubType: 'major',
      majorKeys: MAJOR_KEYS,
      minorKeys: MINOR_KEYS,
      chordList: [],
      // 添加新的状态变量
      isKeySearchMode: false,
      selectedNotes: [],
      // 添加钢琴键盘相关数据
      pianoKeys: PIANO_KEYS,
      groupWidths: GROUP_WIDTHS,
      noteNames: [
        { name: '6', pitch: 'QLP' },
        { name: '升6降7', pitch: 'QLP' },
        { name: '7', pitch: 'QLP' },
        { name: '1', pitch: 'TLP' },
        { name: '升1降2', pitch: 'TLP' },
        { name: '2', pitch: 'TLP' },
        { name: '升2降3', pitch: 'TLP' },
        { name: '3', pitch: 'TLP' },
        { name: '4', pitch: 'TLP' },
        { name: '升4降5', pitch: 'TLP' },
        { name: '5', pitch: 'TLP' },
        { name: '升5降6', pitch: 'TLP' },
        { name: '6', pitch: 'TLP' },
        { name: '升6降7', pitch: 'TLP' },
        { name: '7', pitch: 'TLP' },
        { name: '1', pitch: 'DLP' },
        { name: '升1降2', pitch: 'DLP' },
        { name: '2', pitch: 'DLP' },
        { name: '升2降3', pitch: 'DLP' },
        { name: '3', pitch: 'DLP' },
        { name: '4', pitch: 'DLP' },
        { name: '升4降5', pitch: 'DLP' },
        { name: '5', pitch: 'DLP' },
        { name: '升5降6', pitch: 'DLP' },
        { name: '6', pitch: 'DLP' },
        { name: '升6降7', pitch: 'DLP' },
        { name: '7', pitch: 'DLP' },
        { name: '1', pitch: 'LP' },
        { name: '升1降2', pitch: 'LP' },
        { name: '2', pitch: 'LP' },
        { name: '升2降3', pitch: 'LP' },
        { name: '3', pitch: 'LP' },
        { name: '4', pitch: 'LP' },
        { name: '升4降5', pitch: 'LP' },
        { name: '5', pitch: 'LP' },
        { name: '升5降6', pitch: 'LP' },
        { name: '6', pitch: 'LP' },
        { name: '升6降7', pitch: 'LP' },
        { name: '7', pitch: 'LP' },
        { name: '1', pitch: 'MP' },
        { name: '升1降2', pitch: 'MP' },
        { name: '2', pitch: 'MP' },
        { name: '升2降3', pitch: 'MP' },
        { name: '3', pitch: 'MP' },
        { name: '4', pitch: 'MP' },
        { name: '升4降5', pitch: 'MP' },
        { name: '5', pitch: 'MP' },
        { name: '升5降6', pitch: 'MP' },
        { name: '6', pitch: 'MP' },
        { name: '升6降7', pitch: 'MP' },
        { name: '7', pitch: 'MP' },
        { name: '1', pitch: 'HP' },
        { name: '升1降2', pitch: 'HP' },
        { name: '2', pitch: 'HP' },
        { name: '升2降3', pitch: 'HP' },
        { name: '3', pitch: 'HP' },
        { name: '4', pitch: 'HP' },
        { name: '升4降5', pitch: 'HP' },
        { name: '5', pitch: 'HP' },
        { name: '升5降6', pitch: 'HP' },
        { name: '6', pitch: 'HP' },
        { name: '升6降7', pitch: 'HP' },
        { name: '7', pitch: 'HP' },
        { name: '1', pitch: 'DHP' },
        { name: '升1降2', pitch: 'DHP' },
        { name: '2', pitch: 'DHP' },
        { name: '升2降3', pitch: 'DHP' },
        { name: '3', pitch: 'DHP' },
        { name: '4', pitch: 'DHP' },
        { name: '升4降5', pitch: 'DHP' },
        { name: '5', pitch: 'DHP' },
        { name: '升5降6', pitch: 'DHP' },
        { name: '6', pitch: 'DHP' },
        { name: '升6降7', pitch: 'DHP' },
        { name: '7', pitch: 'DHP' },
        { name: '1', pitch: 'THP' },
        { name: '升1降2', pitch: 'THP' },
        { name: '2', pitch: 'THP' },
        { name: '升2降3', pitch: 'THP' },
        { name: '3', pitch: 'THP' },
        { name: '4', pitch: 'THP' },
        { name: '升4降5', pitch: 'THP' },
        { name: '5', pitch: 'THP' },
        { name: '升5降6', pitch: 'THP' },
        { name: '6', pitch: 'THP' },
        { name: '升6降7', pitch: 'THP' },
        { name: '7', pitch: 'THP' },
        { name: '1', pitch: 'QHP' }
      ],
      audioContext: null,
      highlightedKeys: [],
      // 添加转位相关状态
      selectedInversion: 0,
    }
  },
  computed: {
    availableSubTypes() {
      return CHORD_SUB_TYPES[this.selectedChordType] || []
    },
    inversionOptions() {
      // 根据和弦类型动态生成转位选项
      const type = this.selectedChordType
      let count = 3
      if (type === 'triad') count = 3
      else if (type === 'seventh') count = 4
      else if (type === 'ninth') count = 5
      else if (type === 'eleventh') count = 6
      else if (type === 'thirteenth') count = 7
      return Array.from({ length: count }, (_, i) => ({ label: i === 0 ? '原位' : `第${i}转位`, value: i }))
    },
    currentRootNote() {
      return getRootNote(this.selectedKey, this.selectedDegree)
    },
    theoryText() {
      if (!this.chordList.length) return ''
      const chord = this.chordList[0]
      // 专业分块说明
      const typeMap = {
        major: { func: '主和弦', usage: '常用于句子的起止，表达稳定、明亮。', desc: '由根音、大三度、纯五度组成。' },
        minor: { func: '副和弦', usage: '常用于抒情、柔和氛围。', desc: '由根音、小三度、纯五度组成。' },
        augmented: { func: '色彩和弦', usage: '具有紧张、不稳定的色彩，常用于转调或连接。', desc: '由根音、大三度、增五度组成。' },
        diminished: { func: '色彩和弦', usage: '常用于连接和声，制造悬念。', desc: '由根音、小三度、减五度组成。' },
        major7: { func: '主和弦', usage: '色彩柔和、梦幻，常用于流行、爵士。', desc: '大三和弦加大七度。' },
        dominant7: { func: '属和弦', usage: '常用于进行到主和弦，制造回归感。', desc: '大三和弦加小七度。' },
        minor7: { func: '副和弦', usage: '色彩温暖、爵士感。', desc: '小三和弦加小七度。' },
        'half-diminished7': { func: '色彩和弦', usage: '常用于爵士、流行。', desc: '减三和弦加小七度。' },
        diminished7: { func: '色彩和弦', usage: '色彩极度紧张，常用于连接。', desc: '减三和弦加减七度。' },
        major9: { func: '主和弦', usage: '色彩丰富，常用于流行、爵士。', desc: '大七和弦加九度音。' },
        dominant9: { func: '属和弦', usage: '常用于爵士、蓝调。', desc: '属七和弦加九度音。' },
        minor9: { func: '副和弦', usage: '色彩柔和。', desc: '小七和弦加九度音。' },
        major11: { func: '主和弦', usage: '色彩更丰富。', desc: '大九和弦加十一度音。' },
        dominant11: { func: '属和弦', usage: '常用于爵士。', desc: '属九和弦加十一度音。' },
        minor11: { func: '副和弦', usage: '色彩丰富。', desc: '小九和弦加十一度音。' },
        major13: { func: '主和弦', usage: '极为丰富，常用于现代音乐。', desc: '大十一和弦加十三度音。' },
        dominant13: { func: '属和弦', usage: '常用于爵士、现代音乐。', desc: '属十一和弦加十三度音。' },
        minor13: { func: '副和弦', usage: '色彩丰富。', desc: '小十一和弦加十三度音。' }
      }
      const subType = this.selectedSubType
      const info = typeMap[subType] || { func: '', usage: '', desc: '' }
      const funcColor = info.func.includes('主') ? '#409eff' : info.func.includes('属') ? '#e67e22' : '#8e44ad'
      // 新增所有转位音符排列
      let inversionText = ''
      const notesArr = chord.notes.split(' ')
      const inversionCount = this.inversionOptions.length
      if (inversionCount > 1) {
        inversionText = `<div class='theory-row'><span class='theory-label'>所有转位</span><span class='theory-block'>`
        for (let i = 0; i < inversionCount; i++) {
          const invNotes = this.getChordInversionNotes(notesArr, i)
          const invDegrees = this.getDegreeIntervals(this.selectedKey, invNotes).join(' ')
          inversionText += `${this.inversionOptions[i].label}: ${invDegrees} `
        }
        inversionText += `</span></div>`
      }
      return `
        <div class='theory-card'>
          <div class='theory-title'><b>${chord.cnName}</b></div>
          <div class='theory-row'>
            <span class='theory-label'>结构</span>
            <span class='theory-block'>${chord.intervals}</span>
          </div>
          <div class='theory-row'>
            <span class='theory-label'>音符</span>
            <span class='theory-block'>${this.getChordInversionNotes(notesArr, this.selectedInversion).join(' ')}</span>
          </div>
          ${inversionText}
          <div class='theory-row'>
            <span class='theory-label'>功能</span>
            <span class='theory-tag'>${info.func}</span>
          </div>
          <div class='theory-divider'></div>
          <div class='theory-row'>
            <span class='theory-label'>说明</span>
            <span class='theory-desc'>${info.desc}</span>
          </div>
          <div class='theory-divider'></div>
          <div class='theory-row'>
            <span class='theory-label'>用法</span>
            <span class='theory-usage'>${info.usage}</span>
          </div>
        </div>
      `
    }
  },
  mounted() {
    this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
  },
  methods: {
    // 获取当前条件下的所有和弦
    getAllChords() {
      const chords = []
      const rootNote = this.currentRootNote
      if (!rootNote) return chords

      // 获取当前选择的子类型
      const subType = this.availableSubTypes.find(st => st.value === this.selectedSubType)
      if (!subType) return chords

      const chordNotes = getChordNotes(rootNote, this.selectedChordType, this.selectedSubType)
      if (chordNotes) {
        const chordName = getChordName(rootNote, this.selectedChordType, this.selectedSubType)
        // 计算调式内级数
        const intervals = this.getDegreeIntervals(this.selectedKey, chordNotes)
        chords.push({
          ...chordName,
          intervals: intervals.join(' '),
          notes: chordNotes.join(' '),
          subTypeLabel: subType.label
        })
      }

      return chords
    },
    onQuery() {
      const rootNote = this.currentRootNote
      if (!rootNote) {
        this.showEmpty = true
        this.chordList = []
        this.clearPianoActive()
        return
      }
      this.chordList = this.getAllChords()
      this.showEmpty = this.chordList.length === 0
      if (this.chordList.length > 0) {
        this.$nextTick(() => {
          this.highlightChordKeysDOM()
        })
      } else {
        this.clearPianoActive()
      }
    },
    onKeyChange() {
      this.chordList = []
      this.showEmpty = false
      this.onQuery() // 自动查询
      this.$nextTick(() => {
        this.highlightChordKeysDOM()
      })
    },
    onDegreeChange() {
      this.chordList = []
      this.showEmpty = false
      this.onQuery() // 自动查询
      this.$nextTick(() => {
        this.highlightChordKeysDOM()
      })
    },
    onChordTypeChange() {
      this.selectedSubType = this.availableSubTypes[0]?.value || ''
      this.chordList = []
      this.showEmpty = false
      this.onQuery() // 自动查询
      this.$nextTick(() => {
        this.highlightChordKeysDOM()
      })
    },
    onSubTypeChange() {
      this.chordList = []
      this.showEmpty = false
      this.onQuery() // 自动查询
      this.$nextTick(() => {
        this.highlightChordKeysDOM()
      })
    },
    handlePianoKeyClick(index) {
      if (this.isKeySearchMode) {
        // 按键找音模式下的处理
        const note = this.pianoKeys[index];
        const noteIndex = this.selectedNotes.indexOf(note);
        if (noteIndex === -1) {
          this.selectedNotes.push(note);
        } else {
          this.selectedNotes.splice(noteIndex, 1);
        }
        // 更新高亮状态
        this.highlightSelectedNotes();
        
        // 当选择了3个音符时，尝试更新下拉菜单的值
        if (this.selectedNotes.length === 3) {
          this.updateSelectValuesFromNotes();
        }
      } else {
        // 原有的播放音符逻辑
        const note = this.pianoKeys[index];
        this.playNote(note);
      }
    },
    updateSelectValuesFromNotes() {
      const normalizedNotes = this.selectedNotes.map(note => note.split('/')[0].replace(/\d+/, ''));
      // 遍历所有可能的和弦配置
      for (const key of [...MAJOR_KEYS, ...MINOR_KEYS].map(k => k.value)) {
        for (const chordType of Object.keys(CHORD_TEMPLATES)) {
          for (const subType of Object.keys(CHORD_TEMPLATES[chordType])) {
            const chordNotes = getChordNotes(key, chordType, subType);
            if (!chordNotes) continue;
            const normalizedChordNotes = chordNotes.map(note => note.replace(/\d+/, ''));
            if (this.isNotesMatch(normalizedNotes, normalizedChordNotes)) {
              // 找到匹配的和弦，更新下拉菜单的值
              this.selectedChordType = chordType;
              this.selectedSubType = subType;
              // 计算和弦级数
              const scale = getScale(key);
              const rootIndex = getNoteIndex(key);
              if (rootIndex !== -1) {
                const degree = scale.indexOf((getNoteIndex(normalizedNotes[0]) - rootIndex + 12) % 12) + 1;
                if (degree > 0) {
                  this.selectedDegree = degree.toString();
                }
              }
              return;
            }
          }
        }
      }
    },
    highlightSelectedNotes() {
      const pianoEls = this.$el.querySelectorAll('.piano-key');
      pianoEls.forEach((el, index) => {
        const note = this.pianoKeys[index];
        if (this.selectedNotes.includes(note)) {
          el.classList.add('active');
        } else {
          el.classList.remove('active');
        }
      });
    },
    playNote(note) {
      // 这里可以添加播放音符的逻辑
      console.log('Playing note:', note);
    },
    highlightChordKeysDOM() {
      this.clearPianoActive()
      // 获取当前转位的和弦音符
      let chordNotes = []
      if (this.chordList[0]?.notes) {
        const notesArr = this.chordList[0].notes.split(' ')
        chordNotes = this.getChordInversionNotes(notesArr, this.selectedInversion)
      }
      if (!chordNotes || chordNotes.length === 0) return
      // 以当前转位第一个音为高亮起点，优先找4组
      const firstNote = chordNotes[0]
      let startIdx = -1
      for (let i = 0; i < this.pianoKeys.length; i++) {
        const keyNames = this.pianoKeys[i].split('/')
        if (keyNames.some(k => k.replace(/\d+/, '') === firstNote.replace(/\d+/, '')) && this.pianoKeys[i].endsWith('4')) {
          startIdx = i
          break
        }
      }
      if (startIdx === -1) {
        // 没找到4组，找全局第一个
        startIdx = this.pianoKeys.findIndex(k => k.split('/').some(n => n.replace(/\d+/, '') === firstNote.replace(/\d+/, '')))
        if (startIdx === -1) return
      }
      // 依次高亮转位音符
      const pianoEls = this.$el.querySelectorAll('.piano-key')
      for (let i = 0; i < chordNotes.length; i++) {
        const note = chordNotes[i]
        // 在键盘上找距离startIdx+i最近的等音
        const keyIdx = startIdx + i
        if (keyIdx < this.pianoKeys.length) {
          const keyNames = this.pianoKeys[keyIdx].split('/')
          if (keyNames.some(k => k.replace(/\d+/, '') === note.replace(/\d+/, ''))) {
            if (pianoEls[keyIdx]) pianoEls[keyIdx].classList.add('active')
          } else {
            // 如果不是等音，遍历startIdx附近12个键找等音
            for (let j = 0; j < 12; j++) {
              const tryIdx = startIdx + j
              if (tryIdx < this.pianoKeys.length) {
                const tryNames = this.pianoKeys[tryIdx].split('/')
                if (tryNames.some(k => k.replace(/\d+/, '') === note.replace(/\d+/, ''))) {
                  if (pianoEls[tryIdx]) pianoEls[tryIdx].classList.add('active')
                  break
                }
              }
            }
          }
        }
      }
    },
    clearPianoActive() {
      const pianoEls = this.$el.querySelectorAll('.piano-key')
      pianoEls.forEach(el => el.classList.remove('active'))
    },
    playChord(notesStr) {
      if (!notesStr) return
      const notes = notesStr.split(' ')
      // 找到这些音在pianoKeys中的音频名（优先#，再b，再自然音）
      notes.forEach(note => {
        // 只取4组（如G4、B4等），找不到就找其它组
        let keyIdx = this.pianoKeys.findIndex(k => k.split('/').some(n => n.replace(/\d+/, '') === note.replace(/\d+/, '') && k.endsWith('4')))
        if (keyIdx === -1) {
          keyIdx = this.pianoKeys.findIndex(k => k.split('/').some(n => n.replace(/\d+/, '') === note.replace(/\d+/, '')))
        }
        if (keyIdx !== -1) {
          let keyName = this.pianoKeys[keyIdx]
          // 取第一个音名（如C#4/Db4取C#4，和自由弹唱页面一致）
          let audioName = keyName.split('/')[1] || keyName.split('/')[0]
          const audio = new Audio()
          audio.src = `/audio/salamander/${audioName}.mp3`
          audio.currentTime = 0
          audio.play().catch(() => {})
        }
      })
    },
    playArpeggio(notesStr) {
      if (!notesStr) return
      const notes = notesStr.split(' ')
      notes.forEach((note, idx) => {
        setTimeout(() => {
          let keyIdx = this.pianoKeys.findIndex(k => k.split('/').some(n => n.replace(/\d+/, '') === note.replace(/\d+/, '') && k.endsWith('4')))
          if (keyIdx === -1) {
            keyIdx = this.pianoKeys.findIndex(k => k.split('/').some(n => n.replace(/\d+/, '') === note.replace(/\d+/, '')))
          }
          if (keyIdx !== -1) {
            let keyName = this.pianoKeys[keyIdx]
            let audioName = keyName.split('/')[1] || keyName.split('/')[0]
            const audio = new Audio()
            audio.src = `/audio/salamander/${audioName}.mp3`
            audio.currentTime = 0
            audio.play().catch(() => {})
          }
        }, idx * 120)
      })
    },
    // 获取音名对应的频率
    getFrequency(noteName) {
      // noteName如C4、D#4、F#4
      const noteFreqMap = {
        'C': 261.63, 'C#': 277.18, 'Db': 277.18, 'D': 293.66, 'D#': 311.13, 'Eb': 311.13,
        'E': 329.63, 'F': 349.23, 'F#': 369.99, 'Gb': 369.99, 'G': 392.00, 'G#': 415.30, 'Ab': 415.30,
        'A': 440.00, 'A#': 466.16, 'Bb': 466.16, 'B': 493.88
      }
      const match = noteName.match(/^([A-G][b#]?)(\d)$/)
      if (!match) return 440
      const base = noteFreqMap[match[1]]
      const octave = parseInt(match[2])
      return base * Math.pow(2, octave - 4)
    },
    toggleKeySearchMode() {
      this.isKeySearchMode = !this.isKeySearchMode;
      if (this.isKeySearchMode) {
        // 进入按键找音模式时，清除之前的状态
        this.chordList = [];
        this.showEmpty = false;
        this.clearPianoActive();
        this.selectedNotes = [];
      } else {
        // 退出按键找音模式时，清除所有状态
        this.chordList = [];
        this.showEmpty = false;
        this.clearPianoActive();
        this.selectedNotes = [];
      }
    },
    onConfirmKeySearch() {
      if (this.selectedNotes.length < 3) {
        this.$message.error('请至少选择3个音符');
        return;
      }
      // 获取所有可能的和弦
      const possibleChords = this.findPossibleChords(this.selectedNotes);
      if (possibleChords.length === 0) {
        this.showEmpty = true;
        this.chordList = [];
        this.$message.warning('未找到匹配的和弦');
        return;
      }
      this.chordList = possibleChords;
      this.showEmpty = false;
      // 联动下拉菜单为第一个匹配和弦
      const chord = possibleChords[0];
      if (chord) {
        // 只联动和弦类型、子类型、级数，不联动调式
        this.selectedChordType = this.getChordTypeBySuffix(chord.enName.replace(/^[A-G#b]+/, ''));
        this.selectedSubType = this.getChordSubTypeByCnSuffix(chord.cnName.replace(/^[A-G#b]+/, ''));
        // 级数
        if (chord.intervals && chord.intervals.split(' ').length > 0) {
          this.selectedDegree = chord.intervals.split(' ')[0];
        }
      }
    },
    getChordTypeBySuffix(suffix) {
      // 根据和弦英文名后缀推断类型
      if (suffix === '' || suffix === 'm' || suffix === 'aug' || suffix === 'dim') return 'triad';
      if (suffix.includes('7')) return 'seventh';
      if (suffix.includes('9')) return 'ninth';
      if (suffix.includes('11')) return 'eleventh';
      if (suffix.includes('13')) return 'thirteenth';
      return 'triad';
    },
    getChordSubTypeByCnSuffix(cnSuffix) {
      // 根据中文名后缀推断子类型
      for (const type in CHORD_SUB_TYPES) {
        for (const sub of CHORD_SUB_TYPES[type]) {
          if (cnSuffix.includes(sub.label.replace('和弦', ''))) return sub.value;
        }
      }
      return '';
    },
    findPossibleChords(notes) {
      const chords = [];
      const normalizedNotes = notes.map(note => note.split('/')[0].replace(/\d+/, ''));
      
      // 遍历所有可能的根音
      for (const key of [...MAJOR_KEYS, ...MINOR_KEYS].map(k => k.value)) {
        // 遍历所有和弦类型
        for (const chordType of Object.keys(CHORD_TEMPLATES)) {
          // 遍历所有和弦子类型
          for (const subType of Object.keys(CHORD_TEMPLATES[chordType])) {
            const chordNotes = getChordNotes(key, chordType, subType);
            if (!chordNotes) continue;

            // 检查是否匹配
            const normalizedChordNotes = chordNotes.map(note => note.replace(/\d+/, ''));
            if (this.isNotesMatch(normalizedNotes, normalizedChordNotes)) {
              const chordName = getChordName(key, chordType, subType);
              // 计算调式内级数
              const intervals = this.getDegreeIntervals(key, chordNotes);
              chords.push({
                ...chordName,
                intervals: intervals.join(' '),
                notes: chordNotes.join(' '),
                subTypeLabel: CHORD_SUB_TYPES[chordType].find(st => st.value === subType)?.label
              });
            }
          }
        }
      }
      return chords;
    },
    getDegreeIntervals(key, notes) {
      // key: 调式根音，如C或a
      // notes: 和弦音符数组，如['D','F','A']
      const scale = getScale(key)
      const tonicIndex = getNoteIndex(key)
      if (tonicIndex === -1) return []
      // 构建度数-音的映射表
      const degreeMap = {}
      const degreeNames = ['1','b2','2','#2','3','4','#4','5','#5','6','b7','7']
      // 12个半音
      for (let i = 0; i < 12; i++) {
        // 计算当前半音对应的音名
        const noteIdx = (tonicIndex + i) % 12
        const noteName = NOTES[noteIdx]
        degreeMap[noteName] = degreeNames[i]
      }
      // 允许Db等等音
      FLAT_NOTES.forEach((n, i) => {
        if (!degreeMap[n]) degreeMap[n] = degreeNames[i]
      })
      // 结果
      return notes.map(note => {
        // 只取音名部分
        const n = note.replace(/\d+/, '')
        // 优先自然级数
        if (degreeMap[n]) return degreeMap[n]
        // 兼容#和b的等音
        // 例如D#等于#2，Eb等于b3
        // 先查#
        const sharpIdx = NOTES.indexOf(n)
        if (sharpIdx !== -1 && degreeNames[sharpIdx]) return degreeNames[sharpIdx]
        // 再查b
        const flatIdx = FLAT_NOTES.indexOf(n)
        if (flatIdx !== -1 && degreeNames[flatIdx]) return degreeNames[flatIdx]
        return '-'
      })
    },
    isNotesMatch(notes1, notes2) {
      if (notes1.length !== notes2.length) return false;
      const sortedNotes1 = [...notes1].sort();
      const sortedNotes2 = [...notes2].sort();
      return sortedNotes1.every((note, index) => note === sortedNotes2[index]);
    },
    getChordInversionNotes(notes, inversion) {
      // notes: 原始和弦音符数组
      // inversion: 转位序号
      if (!notes || notes.length === 0) return []
      const arr = [...notes]
      for (let i = 0; i < inversion; i++) {
        arr.push(arr.shift())
      }
      return arr
    },
    onInversionChange() {
      // 切换转位时，重新高亮钢琴键
      this.$nextTick(() => {
        this.highlightChordKeysDOM()
      })
    },
  }
}
</script>

<style scoped>
.chord-dict-container {
  min-height: 100vh;
  background: linear-gradient(135deg, #f7f8fa 0%, #eef2f7 100%);
}
.chord-dict-content {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding-top: 110px;
  min-height: 80vh;
  width: 90%;
  margin: 0 auto;
}
.chord-dict-card {
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 4px 24px rgba(0,0,0,0.08);
  padding: 24px 20px 18px 20px;
  width: 100%;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.search-section {
  width: 100%;
  background: #f8fafc;
  border-radius: 12px;
  padding: 14px 14px 10px 14px;
  margin-bottom: 12px;
}
.search-row {
  display: flex;
  gap: 16px;
  align-items: flex-end;
  flex-wrap: wrap;
}
.key-select {
  flex: 0 0 140px;
  margin-bottom: 0;
}
.degree-select {
  flex: 0 0 160px;
  margin-bottom: 0;
}
.degree-select :deep(.el-select-dropdown__item) {
  padding: 0 20px;
  height: 34px;
  line-height: 34px;
}
.chord-type-select {
  flex: 0 0 140px;
  margin-bottom: 0;
}
.chord-subtype-select {
  flex: 0 0 140px;
  margin-bottom: 0;
}
.search-btn {
  flex: 0 0 100px;
  margin-bottom: 0;
}
.key-search-btn {
  flex: 0 0 100px;
  margin-bottom: 0;
}
.confirm-btn {
  flex: 0 0 100px;
  margin-bottom: 0;
}
.chord-dict-form {
  width: 100%;
}
.chord-dict-btn {
  width: 100%;
  height: 40px;
  font-size: 15px;
  border-radius: 8px;
  font-weight: 600;
}
.chord-list {
  margin-top: 16px;
  width: 100%;
}
.chord-list-title {
  font-size: 15px;
  font-weight: 600;
  color: #222;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.chord-list-title::before {
  content: '';
  display: inline-block;
  width: 4px;
  height: 20px;
  background: #409eff;
  border-radius: 2px;
}

/* 钢琴键盘样式 */
.keyboard-section {
  margin-top: 16px;
  width: 100%;
  min-height: 200px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 24px rgba(0,0,0,0.08);
  display: flex;
  justify-content: center;
  align-items: center;
}
.keyboard-box {
  margin-top: 12px;
  width: 100%;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 24px rgba(0,0,0,0.08);
  overflow: hidden;
}
.piano-bottom {
  height: 175px;
  background: #000;
  width: 100%;
}
.piano {
  display: flex;
  justify-content: space-between;
  background: #fff;
  width: 100%;
  border: 1px solid #000;
  border-top-width: 3px;
  box-sizing: border-box;
  height: 156px;
}
.piano-key {
  width: 2%;
  height: 152px;
  outline: 1px solid #444444;
  background-color: white;
  box-sizing: border-box;
  line-height: 240px;
  text-align: center;
  position: relative;
  border-radius: 0 0 2px 2px;
  border-bottom: 5px solid #eeeeee;
  cursor: pointer;
  -webkit-user-select: none;
  transition: background-color 0.2s ease;
}
.piano-key.black {
  border: none;
  color: #ccc;
  font-size: 12px !important;
  height: 90px;
  display: flex;
  align-items: flex-end;
  padding-bottom: 5px;
  width: 0.9%;
  height: 100px;
  margin: 0 -10px;
  background-color: #444444;
  z-index: 2;
  line-height: normal;
  color: #fff;
  writing-mode: inherit;
}
.piano-key.highlighted-chord {
  background: #e53935 !important;
  color: #fff !important;
  border-bottom: 5px solid #e53935 !important;
  z-index: 3;
}
.piano-key.black.highlighted-chord {
  background: #e53935 !important;
  color: #fff !important;
}
.piano-key.active {
  background: red !important;
  color: #fff !important;
  border-bottom: 5px solid red !important;
}
.piano-key.black.active {
  background: red !important;
  color: #fff !important;
}
.piano-key.active .LP::after,
.piano-key.active .DLP::after,
.piano-key.active .TLP::after,
.piano-key.active .QLP::after,
.piano-key.active .HP::after,
.piano-key.active .DHP::after,
.piano-key.active .THP::after,
.piano-key.active .QHP::after {
  color: #fff !important;
}
.piano-group {
  overflow: hidden;
  border: 1px solid #000;
  border-width: 0 0.1% 0 0.1%;
}
.piano-group li {
  float: left;
  width: auto;
  background: #ccc;
  font-size: 12px;
  color: #333;
}
.group {
  list-style: none;
  text-align: center;
  margin-top: 3px;
  margin-right: 0.1%;
  box-sizing: border-box;
  white-space: nowrap;
}
.group:last-child {
  margin-right: 0;
}

/* 响应式布局 */
@media (max-width: 1200px) {
  .chord-dict-card {
    width: 95vw;
    padding: 32px 24px 24px 24px;
  }
  .search-row {
    gap: 12px;
  }
  .key-select,
  .degree-select,
  .chord-type-select,
  .chord-subtype-select {
    flex: 0 0 calc(50% - 6px);
  }
  .search-btn {
    flex: 0 0 100%;
    margin-top: 12px;
  }
}

@media (max-width: 768px) {
  .chord-dict-content {
    padding-top: 80px;
  }
  .chord-dict-card {
    padding: 24px 16px 16px 16px;
  }
  .search-section {
    padding: 16px;
  }
  .key-select,
  .degree-select,
  .chord-type-select,
  .chord-subtype-select {
    flex: 0 0 100%;
  }
}

.piano-key span::after {
  position: absolute;
  bottom: 36px;
  left: 50%;
  margin-left: -5px;
  display: inline-block;
  width: 10px;
  font-size: 12px;
  line-height: 0;
  text-align: center;
  color: #000;
  writing-mode: tb;
  box-sizing: border-box;
}

.piano-key .LP::after {
  height: 4px;
  content: '.';
}

.piano-key .DLP::after {
  height: 6px;
  content: '..';
}

.piano-key .TLP::after {
  height: 8px;
  content: '...';
}

.piano-key .QLP::after {
  height: 10px;
  content: '....';
}

.piano-key .HP::after {
  height: 4px;
  bottom: 13px;
  content: '.';
}

.piano-key .DHP::after {
  bottom: 10px;
  height: 6px;
  content: '..';
}

.piano-key .THP::after {
  bottom: 8px;
  height: 8px;
  content: '...';
}

.piano-key .QHP::after {
  bottom: 8px;
  height: 8px;
  content: '....';
}

.chord-theory-box {
  margin-top: 8px;
  background: #f8fafc;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.04);
  padding: 8px 12px 8px 12px;
}
.chord-theory-header {
  font-weight: 600;
  font-size: 15px;
  color: #222;
  display: flex;
  align-items: center;
  gap: 4px;
}
.chord-theory-content {
  margin-top: 8px;
  color: #333;
  font-size: 14px;
  line-height: 1.7;
  text-align: left;
}
.theory-card {
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.04);
  padding: 10px 12px 8px 12px;
  margin-top: 4px;
  max-width: 420px;
}
.theory-title {
  font-size: 17px;
  font-weight: bold;
  margin-bottom: 6px;
  color: #222;
  letter-spacing: 1px;
}
.theory-row {
  display: flex;
  align-items: center;
  margin-bottom: 4px;
  font-size: 15px;
}
.theory-label {
  display: inline-block;
  min-width: 56px;
  color: #888;
  font-size: 13px;
  font-weight: 500;
}
.theory-block {
  margin-left: 8px;
  background: #f3f4f7;
  border-radius: 6px;
  padding: 1px 8px;
  font-family: 'Consolas', 'Menlo', 'monospace';
  color: #222;
  font-size: 14px;
}
.theory-tag {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 10px;
  border-radius: 12px;
  font-size: 13px;
  font-weight: 600;
  background: #e53935 !important;
  color: #fff !important;
}
.theory-desc {
  margin-left: 8px;
  color: #555;
  font-size: 13px;
}
.theory-usage {
  margin-left: 8px;
  color: #aaa;
  font-size: 12px;
}
.theory-divider {
  height: 1px;
  background: #ececec;
  margin: 4px 0 4px 0;
  border-radius: 1px;
}
.inversion-select {
  flex: 0 0 140px;
  margin-bottom: 0;
}
.btn-group {
  display: flex;
  gap: 12px;
  margin-left: auto;
}
</style> 